import collections

class Zrange:
    def __init__(self, n):
        self.n = n
    
    def __iter__(self):
        return ZrangeIterator(self.n)

class ZrangeIterator:
    def __init__(self, n):
        self.i = 0
        self.n = n

    def __iter__(self):
        return self

    def __next__(self):
        if self.i < self.n:
            i = self.i
            self.i = i + 1
            return i
        else:
            raise StopIteration()

# zrange = Zrange(3)
# print(isinstance(iter(zrange), collections.Iterator))
# print([i for i in zrange])



class Zrange2:
    def __init__(self, n):
        self.n = n

    def __iter__(self):
        return self.__generator()

    def __generator(self):
        i = 0
        while i < self.n:
            yield i
            i += 1


# print(isinstance(iter(Zrange(3)), collections.Iterator))
# print([i for i in Zrange2(3)])
# print([i for i in Zrange2(3)])


#代理迭代

class Node:
    def __init__(self, value):
        self._value = value
        self._children = []

    def __repr__(self):
        return 'Node({})'.format(self._value)

    def add_child(self, child):
        self._children.append(child)

    def __iter__(self):
        return iter(self._children)

    def depth_first(self):
        yield self
        for c in self:
            yield from c.depth_first()

root = Node(0)
child1 = Node(1)
child2 = Node(2)
root.add_child(child1)
root.add_child(child2)
for ch in root:
    print(ch)
for ch in root.depth_first():
    print(ch) 